#include "HiMediaSystem.h"
#include <sys/time.h>
#include "hi_comm_vb.h"
#include "mpi_sys.h"
#include "mpi_vb.h"
#include "hi_buffer.h"
#include "hi_mapi_sys.h"


namespace HiADAS {

HI_S32 HiMediaSystem::Init(HI_U32 vcapPipe, HI_U32 videoWidth, HI_U32 videoHeight)
{
    HI_S32 ret = HI_FAILURE;
    /* init system */
    HI_MAPI_Sys_Init();
    /* init VB and media */
    InitVB(vcapPipe, videoWidth, videoHeight);
    return ret;
}

HI_S32 HiMediaSystem::InitVB(HI_U32 vcapPipe, HI_U32 videoWidth, HI_U32 videoHeight)
{
    HI_S32 ret;
    HI_MAPI_MEDIA_ATTR_S mediaSys;
    HI_U32 blkSize;

    memset(&mediaSys, 0, sizeof(mediaSys));

    mediaSys.stMediaConfig.stVIVPSSMode.aenMode[vcapPipe] = VI_OFFLINE_VPSS_OFFLINE;
    mediaSys.stMediaConfig.stVbConfig.u32MaxPoolCnt = 3;

    blkSize = COMMON_GetPicBufferSize(videoWidth, videoHeight,
                                        PIXEL_FORMAT_YVU_SEMIPLANAR_420,
                                        DATA_BITWIDTH_8, COMPRESS_MODE_NONE,
                                        DEFAULT_ALIGN);
    mediaSys.stMediaConfig.stVbConfig.astCommPool[0].u64BlkSize = blkSize;
    mediaSys.stMediaConfig.stVbConfig.astCommPool[0].u32BlkCnt = 6;
    printf("1080p,size:%d \n", blkSize*2);

    blkSize = COMMON_GetPicBufferSize(1280, 720,
                                        PIXEL_FORMAT_YVU_SEMIPLANAR_420,
                                        DATA_BITWIDTH_8, COMPRESS_MODE_NONE,
                                        DEFAULT_ALIGN);
    mediaSys.stMediaConfig.stVbConfig.astCommPool[1].u64BlkSize = blkSize;
    mediaSys.stMediaConfig.stVbConfig.astCommPool[1].u32BlkCnt = 3;
    printf("1400*880,size:%d \n", blkSize*3);

    // blkSize = VI_GetRawBufferSize(videoWidth, videoHeight,
    //                                 PIXEL_FORMAT_RGB_BAYER_16BPP,
    //                                 COMPRESS_MODE_NONE, DEFAULT_ALIGN);
    // mediaSys.stMediaConfig.stVbConfig.astCommPool[2].u64BlkSize = blkSize;
    // mediaSys.stMediaConfig.stVbConfig.astCommPool[2].u32BlkCnt = 2;

    // mediaSys.stVencModPara.u32H264eLowPowerMode = 1;
    // mediaSys.stVencModPara.u32H265eLowPowerMode = 1;
    ret = HI_MAPI_Media_Init(&mediaSys);
    if (ret != HI_SUCCESS) {
        printf("Error, HI_MAPI_Media_Init ret=0x%08x\n", ret);
    }
    return ret;
}

HI_S32 HiMediaSystem::Deinit(void)
{
    HI_S32 ret = HI_FAILURE;
    HI_MAPI_Media_Deinit();
    HI_MAPI_Sys_Deinit();
    return ret;
}

HI_S32 HiMediaSystem::MallocMem(HI_U64 *phyAddr, HI_VOID **virAddr, HI_U32 size, const HI_CHAR* pszMemName)
{
    HI_S32 ret = HI_SUCCESS;
    ret = HI_MPI_SYS_MmzAlloc(phyAddr, virAddr, pszMemName, NULL, size);
    return ret;
}

HI_S32 HiMediaSystem::MallocMemCached(HI_U64 *phyAddr, HI_VOID **virAddr, HI_U32 size, const HI_CHAR* pszMemName)
{
    return HI_MPI_SYS_MmzAlloc_Cached(phyAddr, virAddr, pszMemName, NULL, size);
}

HI_S32 HiMediaSystem::FreeMem(HI_U64 phyAddr, HI_U64 virAddr)
{
    HI_MPI_SYS_MmzFree(phyAddr,(void*)(HI_UL)(virAddr));

    return 0;
}

HI_S32 HiMediaSystem::FlushCache(HI_U64 phyAddr, HI_VOID *virAddr, HI_U32 size)
{
    return HI_MPI_SYS_MmzFlushCache(phyAddr, virAddr, size);
}

HI_U32 HiMediaSystem::NowTime(HI_VOID)
{
    struct timeval tv;
    gettimeofday(&tv , NULL);
    HI_U32 timeMs = ((HI_U64)tv.tv_sec * 1000000 + tv.tv_usec)/1000;
//    printf("now time(ms): %d\n", timeMs);
    return timeMs;
}

}
